﻿module Tutorial

open Lidgren.Network
open System

let config:NetPeerConfiguration = NetPeerConfiguration("Test")
config.Port <- 14242

let server_read (server:NetServer) =
  let mutable msg = server.ReadMessage()
  Console.Write("Waiting for clients...")
  while true do
    if msg <> null then
      match msg.MessageType with
        |NetIncomingMessageType.VerboseDebugMessage -> Console.WriteLine(msg.ReadString())
        |NetIncomingMessageType.DebugMessage -> Console.WriteLine(msg.ReadString())
        |NetIncomingMessageType.WarningMessage -> Console.WriteLine(msg.ReadString())
        |NetIncomingMessageType.ErrorMessage -> Console.WriteLine(msg.ReadString())
        |NetIncomingMessageType.DiscoveryRequest -> 
          let response = server.CreateMessage()
          Console.Clear()
          Console.WriteLine("New client connected!")
          response.Write("Hello! I'm the server... Prepare to die!")
          server.SendDiscoveryResponse(response, msg.SenderEndpoint)
        |_ -> Console.WriteLine("ERROR: unhandled message type")
      server.Recycle(msg)
    else
        Console.Write(".")
        System.Threading.Thread.Sleep(1000)
    msg <- server.ReadMessage()

let client_read (client:NetClient) =
  let mutable msg = client.ReadMessage()
  let mutable server_found = false
  Console.Clear()
  Console.Write("Looking for server...")
  while not server_found do
    if msg <> null then
      match msg.MessageType with
        |NetIncomingMessageType.DiscoveryResponse -> 
          Console.WriteLine("Found server at" + msg.SenderEndpoint.ToString() + "name: " + msg.ReadString())
          server_found <- true
        |_ -> ()
      client.Recycle(msg)
    else 
      Console.Write(".")
      System.Threading.Thread.Sleep(1000)
    msg <- client.ReadMessage()

let mutable is_server = false
Console.WriteLine("S: create server")
Console.WriteLine("C: create client")

let rec key_press (char_event_list:seq<char * (unit -> unit)>) =
  let key_pressed = Console.ReadKey().KeyChar
  match char_event_list |> Seq.tryFind (fun (c,_) -> c = key_pressed) with
  | Some (_,r) -> r()
  | None -> key_press char_event_list

let set_server() = is_server <- true
do key_press ['C', id;'c', id;'S', set_server;'s', set_server]
if is_server then
  let server = NetServer(config)
  server.Start()
  server_read server
else
  let client = NetClient(config)
  config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse)
  client.DiscoverLocalPeers(14242)
  client_read client
